import { Observable } from 'rxjs';
import { App, h, render, ComponentOptions, toRefs } from 'vue';
import AModal, { destroyFns } from 'ant-design-vue/lib/modal/Modal';
import APagination from 'ant-design-vue/lib/pagination/Pagination';
import AConfigProvider from 'ant-design-vue/lib/config-provider/index';
import { useLocaleStoreWithOut } from '/@/shared/store/vbenModules/locale';
import enUS from 'ant-design-vue/es/locale/en_US';
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import './index.less';
import ModalClose from './modal-close.vue';
import { useModalDragMove } from './useModalDrag';

/** 模态框的配置 */
export interface IModalOptions2 {
  /** Modal 完全关闭后的回调 - function */
  afterClose?: Function;
  /** Modal body 样式 -	object */
  bodyStyle?: Function;
  /** 垂直居中展示 Modal - boolean */
  centered?: boolean;
  /** 是否显示右上角的关闭按钮 - boolean */
  closable?: boolean;
  /** 自定义关闭图标 - boolean */
  closeIcon?: (() => VueNode) | VueNode;
  /** 确定按钮 loading - boolean */
  confirmLoading?: boolean;
  /** 关闭时销毁 Modal 里的子元素 - boolean */
  destroyOnClose?: boolean;
  /** 底部内容，当不需要默认底部按钮时，可以设为 :footer="null" - boolean */
  footer?: string | (() => VueNode);
  /** 强制渲染 Modal - boolean */
  forceRender?: boolean;
  /** 指定 Modal 挂载的 HTML 节点 - (instance): HTMLElement	*/
  getContainer?: () => HTMLElement;
  /** 是否支持键盘 esc 关闭 - boolean */
  keyboard?: boolean;
  /** 是否展示遮罩 - boolean */
  mask?: boolean;
  /** 点击蒙层是否允许关闭 - boolean */
  maskClosable?: boolean;
  /** 遮罩样式 - object */
  maskStyle?: object;
  /** 宽度 */
  width?: string | number;
  /** 设置 Modal 的 z-index */
  zIndex?: number;
  /** 可用于设置浮层的样式，调整浮层位置等	 */
  dialogStyle?: object;
  /** 可用于设置浮层的类名	 */
  dialogClass?: string;
  /** 是否显示 */
  visible?: boolean;
  // 函数
  /** 确认 */
  onOk?: (e) => void;
  /** 取消 */
  onCancel?: (e) => void;
  /**是否全屏 */
  fullScreen?: boolean;
}

export class ModalService {
  private _app;
  public init(app: App) {
    this._app = app;
  }

  /**
   * 创建模态框
   * @param component 组件
   * @param params 组件参数
   * @param options 模态框选项
   * @returns
   */
  create(
    component: ComponentOptions | any,
    params?: any,
    options?: IModalOptions2,
  ): Observable<any> {
    const locale = useLocaleStoreWithOut().getLocale;
    // 1. 处理参数
    // 2. 动态创建要渲染的组件X
    // 3. 将组件X添加到动态创建的模态框中并渲染
    return new Observable<boolean | any>((obs) => {
      // 初始化检查
      if (!this._app) {
        // 没有初始化，抛出异常
        throw '_app is undefined';
      }

      // 模态框容器
      const container = document.createElement('div');
      document.body.appendChild(container);

      // 输入参数
      params = params ? params : {};

      // 基本配置
      options = options ? options : {};
      options.visible = true;
      options.closable = true;
      options.width = params.width;
      options.fullScreen = false;

      destroyFns;

      // 模态框引用
      const modalRef = {
        instance: null,
        close(args: boolean | any) {
          (this.instance as any).component.props.visible = false;

          // 输出结果
          obs.next(args);
          obs.complete();

          // 弹出框关闭时移除节点
          setTimeout(() => {
            document.body.removeChild(container);
          }, 1000);
        },
        unClose(args: boolean | any) {
          (this.instance as any).component.props.visible = true;
          // 输出结果
          obs.next(args);
        },
        fullScreen() {
          if ((this.instance as any).component.props.wrapClassName == 'fullscreen-modal') {
            (this.instance as any).component.props.wrapClassName = '';
          } else {
            (this.instance as any).component.props.wrapClassName = 'fullscreen-modal';
          }
        },

        onChange: (pageIndex) => { },
        pageDataList: [],
      };

      const { pageDataList = [] } = params;
      modalRef.pageDataList = pageDataList;
      const aPagination =
        pageDataList.length > 1
          ? h(APagination, {
            pageSize: 1,
            total: pageDataList.length,
            class: 'g-modal-pagination',
            size: 'small',
            onChange(page) {
              modalRef.onChange(page);
            },
          })
          : null;

      // 组件实例
      const componentInstance = h(
        component,
        {
          ...params,
          modalRef,
        },
        () => aPagination,
      );

      const provider = h(
        AConfigProvider,
        {
          locale: locale === 'en' ? enUS : zhCN,
        },
        () => componentInstance,
      );
      const closeIcon = h(
        ModalClose,
        {
          onCancel() {
            modalRef.close(false);
          },
          onFullscreen() {
            modalRef.fullScreen();
          },
        },
        null,
      );
      // 模态框实例
      const vm = h(
        AModal,
        {
          visible: options.visible,
          width: options.width ? options.width : 900,
          centered: true,
          mask: true,
          maskClosable: false,
          title: '',
          footer: '',
          wrapClassName: options.fullScreen ? 'fullscreen-modal' : '',
          getContainer: () => container,
          closeIcon: closeIcon,
          onCancel: () => {
            modalRef.close(false);
          },
          onOk: () => {
            modalRef.close(true);
          },
        },
        () => provider,
      );

      modalRef.instance = vm as any;

      // 这里很重要，关联app上下文
      vm.appContext = this._app._context;
      render(vm, container);
      const { visible } = toRefs(vm.component.props);
      useModalDragMove({
        visible: visible,
        dragHandler: '.modal-header',
      });
    });
  }
}

const modalHelper = new ModalService();
export default modalHelper;
